home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / type1rd.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  33KB  |  1,606 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    type1rd -
  19.  *        Read an Adobe type 1 font into objfnt data structure.
  20.  *
  21.  *                Paul Haeberli - 1990
  22.  */
  23. #include "stdio.h"
  24. #include "ctype.h"
  25. #include "string.h"
  26. #include "vect.h"
  27. #include "math.h"
  28. #include "objfnt.h"
  29.  
  30. /*
  31.  *    The rest of this file is could be put into a library!
  32.  *
  33.  */
  34. static void runprog();
  35.  
  36. #define LINELEN     (2048)
  37. #define SKIP         (4)
  38. #define NOTHEX        (100)
  39. #define MAXSUBRS     (1000)
  40. #define MAXCHARS     (1000)
  41. #define MAXTRIES     (30)
  42.  
  43. #define dfprintf    nothing
  44.  
  45. static int debugtype1;
  46.  
  47. setdebugtype1(val) 
  48. int val;
  49. {
  50.     debugtype1 = val;
  51. }
  52.  
  53. static nothing()
  54. {
  55. }
  56.  
  57. /* 
  58.  *    font data globals
  59.  *
  60.  */
  61. static char oneline[LINELEN];
  62. static char fname[100];
  63. static float beztol;
  64. static unsigned char *subrs[MAXSUBRS];
  65. static unsigned int sublen[MAXSUBRS];
  66. static unsigned char *chars[MAXCHARS];
  67. static unsigned int charlen[MAXCHARS];
  68. static char *charname[MAXCHARS];
  69. static int nsubrs, nchars;
  70. static char tok[LINELEN];
  71. static FILE *inf;
  72. static unsigned char hextab[256];
  73. static int firsted;
  74.  
  75. static unsigned char *bindat;
  76. static int datbytes;
  77. static int fakepos;
  78. static int fakemax;
  79.  
  80. /* 
  81.  *    interpreter globals
  82.  *
  83.  */
  84. static float mat[2][2];
  85. static unsigned char *pcstack[100];
  86. static unsigned char *pc;
  87. static int pcsp;
  88. static int coordpos;
  89. static int coordsave[7][2];
  90. static int incusp;
  91. static int retstack[1000];
  92. static int retsp;
  93. static int stack[1000];
  94. static int sp;
  95.  
  96. /*
  97.  *    interpreter geometry
  98.  *
  99.  */
  100. static int x_offset, y_offset;    /* offsets for accents */
  101. static int thecharwidth;
  102. static int nvertpos;
  103. static int startx, starty;
  104. static int curx, cury;
  105. static int nextx, nexty;
  106. static int delx, dely;
  107. static int started;
  108.  
  109. /*
  110.  * generic routines 
  111.  *
  112.  */
  113. static void applymat(float mat[2][2], double *x, double *y)    
  114. {                     /* use doubles don't change!! */
  115.     float tx, ty;
  116.  
  117.     tx = (*x)*mat[0][0]+(*y)*mat[0][1];
  118.     ty = (*x)*mat[1][0]+(*y)*mat[1][1];
  119.     *x = tx;
  120.     *y = ty;
  121. }
  122.  
  123. /*
  124.  * poly output stuff 
  125.  *
  126.  */
  127. static int npnts, nloops;
  128. static short chardata[2000];
  129. static int nshorts;
  130.  
  131. static void poly_width(int x)
  132. {
  133.     double fx, fy;
  134.  
  135.     fx = x;
  136.     fy = 0.0;
  137.     applymat(mat,&fx,&fy);
  138.     thecharwidth = (int)(fx + 0.5);
  139. }
  140.  
  141. static void poly_beginchar()
  142. {
  143.     npnts = 0;
  144.     nloops = 0;
  145. }
  146.  
  147. static void poly_endchar()
  148. {
  149.     if(nloops == 0)
  150.     chardata[nshorts++] = PO_RET;
  151.     else
  152.     chardata[nshorts++] = PO_RETENDLOOP;
  153. }
  154.  
  155. static void poly_close()
  156. {
  157.     if(npnts) {
  158.     chardata[nvertpos] = npnts;
  159.     npnts = 0;
  160.     }
  161. }
  162.  
  163. static void poly_pnt(double x, double y)
  164. {
  165.     short v[3];
  166.     int ix, iy;
  167.  
  168.     applymat(mat,&x,&y);
  169.     ix = floor(x);
  170.     iy = floor(y);
  171.     ix += x_offset;
  172.     iy += y_offset;
  173.     if(npnts == 0) {
  174.     if(nloops == 0)
  175.         chardata[nshorts++] = PO_BGNLOOP;
  176.     else 
  177.         chardata[nshorts++] = PO_ENDBGNLOOP;
  178.     nvertpos = nshorts;
  179.     chardata[nshorts++] = 0;
  180.     nloops++;
  181.     }
  182.     chardata[nshorts++] = ix;
  183.     chardata[nshorts++] = iy;
  184.     npnts++;
  185. }
  186.  
  187. /*
  188.  * spline output stuff 
  189.  *
  190.  */
  191. static int sp_npnts, sp_nloops;
  192. static short sp_chardata[2000];
  193. static int sp_nshorts;
  194.  
  195. static void spline_width(int x)
  196. {
  197.     double fx, fy;
  198.  
  199.     fx = x;
  200.     fy = 0.0;
  201.     applymat(mat,&fx,&fy);
  202.     thecharwidth = (int)(fx + 0.5);
  203. }
  204.  
  205. static void spline_beginchar()
  206. {
  207.     sp_npnts = 0;
  208.     sp_nloops = 0;
  209. }
  210.  
  211. static void spline_endchar()
  212. {
  213.     if(sp_nloops == 0)
  214.     sp_chardata[sp_nshorts++] = SP_RET;
  215.     else
  216.     sp_chardata[sp_nshorts++] = SP_RETCLOSEPATH;
  217. }
  218.  
  219. static void spline_close()
  220. {
  221.     sp_chardata[sp_nshorts++] = SP_CLOSEPATH;
  222.     sp_npnts = 0;
  223. }
  224.  
  225. static void spline_line(double x0,double y0,double x1,double y1)
  226. {
  227.     applymat(mat,&x0,&y0);
  228.     applymat(mat,&x1,&y1);
  229.     if(sp_npnts == 0) {
  230.     sp_chardata[sp_nshorts++] = SP_MOVETO;
  231.     sp_chardata[sp_nshorts++] = floor(x0);
  232.     sp_chardata[sp_nshorts++] = floor(y0);
  233.     sp_npnts++;
  234.     sp_nloops++;
  235.     }
  236.     sp_chardata[sp_nshorts++] = SP_LINETO;
  237.     sp_chardata[sp_nshorts++] = floor(x1);
  238.     sp_chardata[sp_nshorts++] = floor(y1);
  239.     sp_npnts++;
  240. }
  241.  
  242. static void spline_curveto(double x0,double y0,double x1,double y1,
  243.                   double x2,double y2,double x3,double y3)
  244. {
  245.     applymat(mat,&x0,&y0);
  246.     applymat(mat,&x1,&y1);
  247.     applymat(mat,&x2,&y2);
  248.     applymat(mat,&x3,&y3);
  249.     if(sp_npnts == 0) {
  250.     sp_chardata[sp_nshorts++] = SP_MOVETO;
  251.     sp_chardata[sp_nshorts++] = floor(x0);
  252.     sp_chardata[sp_nshorts++] = floor(y0);
  253.     sp_npnts++;
  254.     sp_nloops++;
  255.     }
  256.     sp_chardata[sp_nshorts++] = SP_CURVETO;
  257.     sp_chardata[sp_nshorts++] = floor(x1);
  258.     sp_chardata[sp_nshorts++] = floor(y1);
  259.     sp_chardata[sp_nshorts++] = floor(x2);
  260.     sp_chardata[sp_nshorts++] = floor(y2);
  261.     sp_chardata[sp_nshorts++] = floor(x3);
  262.     sp_chardata[sp_nshorts++] = floor(y3);
  263. }
  264.  
  265. /* 
  266.  *    graphics follows 
  267.  *
  268.  *
  269.  */
  270. static void getmove(int *x,int *y)
  271. {
  272.     *x = delx;
  273.     *y = dely;
  274. }
  275.  
  276. static void getpos(int *x,int *y)
  277. {
  278.     *x = curx;
  279.     *y = cury;
  280. }
  281.  
  282. static void savestart(int x,int y)
  283. {
  284.     startx = x;
  285.     starty = y;
  286.     started = 1;
  287. }
  288.  
  289. static void sbpoint(int x,int y)
  290. {
  291.     curx = x;
  292.     cury = y;
  293. }
  294.  
  295. static void moveto(int x,int y)
  296. {
  297.     curx = x;
  298.     cury = y;
  299.     savestart(curx,cury);
  300. }
  301.  
  302. static void rmoveto(int x,int y)
  303. {
  304.     if(incusp) {
  305.     delx = x;
  306.     dely = y;
  307.     } else {
  308.     curx += x;
  309.     cury += y;
  310.     savestart(curx,cury);
  311.     }
  312. }
  313.  
  314. static void drawline(float x0,float y0,float x1,float y1,
  315.                float dx0,float dy0,float dx1,float dy1)
  316. {
  317.     if(x0!=x1 || y0!=y1) 
  318.     poly_pnt(x1,y1);
  319. }
  320.  
  321. static void rlineto(int x,int y)
  322. {
  323.     float dx, dy;
  324.  
  325.     nextx = curx + x;
  326.     nexty = cury + y;
  327.     dx = nextx-curx;
  328.     dy = nexty-cury;
  329.     drawline((float)curx,(float)cury,(float)nextx,(float)nexty,dx,dy,dx,dy);
  330.     spline_line((float)curx,(float)cury,(float)nextx,(float)nexty);
  331.     curx = nextx;
  332.     cury = nexty;
  333. }
  334.  
  335. static void closepath()
  336. {
  337.     float dx, dy;
  338.  
  339.     if(started) {
  340.     dx = startx-curx;
  341.     dy = starty-cury;
  342.     drawline((float)curx,(float)cury,(float)startx,(float)starty,dx,dy,dx,dy);
  343.     poly_close();
  344.     spline_close();
  345.     started = 0;
  346.     }
  347. }
  348.  
  349. static void bezadapt(float x0,float y0,float x1,float y1,
  350.                float x2,float y2,float x3,float y3,float beztol)
  351. {
  352.     float ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3;
  353.     float bx0,by0,bx1,by1,bx2,by2,bx3,by3;
  354.     float midx, midy;
  355.     float linx, liny, dx, dy, mag;
  356.    
  357.     midx = (x0+3*x1+3*x2+x3)/8.0;
  358.     midy = (y0+3*y1+3*y2+y3)/8.0;
  359.     linx = (x0+x3)/2.0;
  360.     liny = (y0+y3)/2.0;
  361.     dx = midx-linx;
  362.     dy = midy-liny;
  363.     mag = dx*dx+dy*dy;
  364.     if(mag<(beztol*beztol))
  365.     drawline(x0,y0,x3,y3,x1-x0,y1-y0,x3-x2,y3-y2);
  366.     else {
  367.     ax0 = x0;
  368.     ay0 = y0;
  369.     ax1 = (x0+x1)/2;
  370.     ay1 = (y0+y1)/2;
  371.     ax2 = (x0+2*x1+x2)/4;
  372.     ay2 = (y0+2*y1+y2)/4;
  373.     ax3 = midx;
  374.     ay3 = midy;
  375.     bezadapt(ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3,beztol);
  376.  
  377.     bx0 = midx;
  378.     by0 = midy;
  379.     bx1 = (x1+2*x2+x3)/4;
  380.     by1 = (y1+2*y2+y3)/4;
  381.     bx2 = (x2+x3)/2;
  382.     by2 = (y2+y3)/2;
  383.     bx3 = x3;
  384.     by3 = y3;
  385.     bezadapt(bx0,by0,bx1,by1,bx2,by2,bx3,by3,beztol);
  386.     }
  387. }
  388.  
  389. static void drawbez(float x0,float y0,float x1,float y1,
  390.                   float x2,float y2,float x3,float y3)
  391. {
  392.     bezadapt(x0,y0,x1,y1,x2,y2,x3,y3,beztol);
  393. }
  394.  
  395. static void rcurveto(int dx1,int dy1,int dx2,int dy2,int dx3,int dy3)
  396. {
  397.     int x0, y0;
  398.     int x1, y1;
  399.     int x2, y2;
  400.     int x3, y3;
  401.  
  402.     x0 = curx;
  403.     y0 = cury;
  404.     x1 = curx+dx1;
  405.     y1 = cury+dy1;
  406.     x2 = curx+dx2;
  407.     y2 = cury+dy2;
  408.     x3 = curx+dx3;
  409.     y3 = cury+dy3;
  410.     drawbez((float)x0,(float)y0,(float)x1,(float)y1,(float)x2,(float)y2,(float)x3,(float)y3);
  411.     spline_curveto((float)x0,(float)y0,(float)x1,(float)y1,
  412.                        (float)x2,(float)y2,(float)x3,(float)y3);
  413.     curx = x3;
  414.     cury = y3;
  415. }
  416.  
  417. /*
  418.  *    read the font matrix out of the font file
  419.  *    update global fname with the actual font name.
  420.  *
  421.  */
  422. static void readfontmatrix(char *name, float mat[2][2])
  423. {
  424.     FILE *inf;
  425.     char *cptr;
  426.     float a, b, c, d, e, f;
  427.  
  428. /* open the input file */
  429.     inf = fopen(name,"r");
  430.     if(!inf) {
  431.     fprintf(stderr,"fromtype1: can't open input file %s\n",name);
  432.     exit(1);
  433.     }
  434.  
  435. /* look for the FontName and FontMatrix def */
  436.     while(1) {
  437.     if(!fgets(oneline,LINELEN,inf)) {
  438.         fprintf(stderr,"fromtype1: no FontMatrix found\n");
  439.         exit(1);
  440.     }
  441.     cptr = strchr(oneline,'/');
  442.     if(cptr) {
  443.             if(strncmp(cptr,"/FontName",9) == 0) {
  444.                 cptr = strchr(cptr+1,'/');
  445.                 if(!cptr) {
  446.                     fprintf(stderr,"fromtype1: bad FontName line\n");
  447.                     exit(1);
  448.                 }
  449.                 sscanf(cptr+1,"%s\n", fname);
  450.             } else {
  451.             if(strncmp(cptr,"/FontMatrix",11) == 0) {
  452.             cptr = strchr(cptr,'[');
  453.             if(!cptr) {
  454.                 fprintf(stderr,"fromtype1: bad FontMatrix line\n");
  455.                 exit(1);
  456.             }
  457.             sscanf(cptr+1,"%f %f %f %f %f %f\n",&a,&b,&c,&d,&e,&f);
  458.                     if (*fname != NULL)
  459.                 break;
  460.             }
  461.             }
  462.     }
  463.     }
  464.     if (*fname == NULL) {
  465.         fprintf(stderr,"fromtype1: bad FontName\n");
  466.         exit(1);
  467.     }
  468.     fclose(inf);
  469.     mat[0][0] = 1000.0*a; 
  470.     mat[0][1] = 1000.0*c; 
  471.     mat[1][0] = 1000.0*b; 
  472.     mat[1][1] = 1000.0*d; 
  473. }
  474.  
  475. /*
  476.  *    Decryption support
  477.  *
  478.  */
  479. static unsigned short mr;
  480.  
  481. static void resetdecrypt(int n)
  482. {
  483.     mr = n;
  484. }
  485.  
  486. static void decryptdata(unsigned char *iptr,unsigned char *optr,int n)
  487. {
  488.     unsigned char in;
  489.     unsigned short mymr;
  490.     unsigned short c1;
  491.     unsigned short c2;
  492.  
  493.     mymr = mr;
  494.     c1 = 52845;
  495.     c2 = 22719;
  496.     while(n>8) {
  497.     in = iptr[0];
  498.     optr[0] = (in^(mymr>>8));
  499.     mymr = (in+mymr)*c1 + c2;
  500.     in = iptr[1];
  501.     optr[1] = (in^(mymr>>8));
  502.     mymr = (in+mymr)*c1 + c2;
  503.     in = iptr[2];
  504.     optr[2] = (in^(mymr>>8));
  505.     mymr = (in+mymr)*c1 + c2;
  506.     in = iptr[3];
  507.     optr[3] = (in^(mymr>>8));
  508.     mymr = (in+mymr)*c1 + c2;
  509.     in = iptr[4];
  510.     optr[4] = (in^(mymr>>8));
  511.     mymr = (in+mymr)*c1 + c2;
  512.     in = iptr[5];
  513.     optr[5] = (in^(mymr>>8));
  514.     mymr = (in+mymr)*c1 + c2;
  515.     in = iptr[6];
  516.     optr[6] = (in^(mymr>>8));
  517.     mymr = (in+mymr)*c1 + c2;
  518.     in = iptr[7];
  519.     optr[7] = (in^(mymr>>8));
  520.     mymr = (in+mymr)*c1 + c2;
  521.     n-=8;
  522.     optr+=8;
  523.     iptr+=8;
  524.     }
  525.     while(n--) {
  526.     in = iptr[0];
  527.     optr[0] = (in^(mymr>>8));
  528.     mymr = (in+mymr)*c1 + c2;
  529.     optr++;
  530.     iptr++;
  531.     }
  532.     mr = mymr;
  533. }
  534.  
  535. static int decryptprogram(unsigned char *buf,int len)
  536. {
  537.     resetdecrypt(4330);
  538.     if(len<4) {
  539.     printf("bad char program\n");
  540.     exit(1);
  541.     }
  542.     decryptdata(buf,buf,SKIP);
  543.     decryptdata(buf+SKIP,buf,len-SKIP);
  544.     return len-SKIP;
  545. }
  546.  
  547. static void decryptall()
  548. {
  549.     int i;
  550.  
  551.     for(i=0; i<nsubrs; i++)
  552.     sublen[i] = decryptprogram(subrs[i],sublen[i]);
  553.     for(i=0; i<nchars; i++) 
  554.     charlen[i] = decryptprogram(chars[i],charlen[i]);
  555. #ifdef FINDIT
  556.     for(i=0; i<nchars; i++) 
  557.     printchardata(i);
  558. #endif
  559. }
  560.  
  561. /*
  562.  *    decode the eexec part of the file
  563.  *
  564.  */
  565. static unsigned char *decodetype1(char *inname)
  566. {
  567.     FILE *inf, *outf;
  568.     unsigned char *hptr, *bptr;
  569.     int i, totlen, hexbytes, c;
  570.     unsigned char *hexdat;
  571.     unsigned char *decdat;
  572.  
  573. /* make hex table */
  574.     if(!firsted) {
  575.     for(i=0; i<256; i++) {
  576.         if(i>='0' && i<='9')
  577.          hextab[i] = i-'0';
  578.         else if(i>='a' && i<='f')
  579.          hextab[i] = 10+i-'a';
  580.         else if(i>='A' && i<='F')
  581.          hextab[i] = 10+i-'A';
  582.         else
  583.          hextab[i] = NOTHEX;
  584.     }
  585.     }
  586.  
  587. /* open input file */
  588.     inf = fopen(inname,"r");
  589.     if(!inf) {
  590.     fprintf(stderr,"fromtype1: can't open input file\n");
  591.     exit(1);
  592.     }
  593.  
  594. /* allocate buffers */
  595.     totlen = sizeoffile(inf);
  596.     hexdat = (unsigned char *)mymalloc(totlen);
  597.     decdat = (unsigned char *)mymalloc(totlen/2);
  598.  
  599. /* look for eexec part of file */
  600.     while(1) {
  601.     if(!fgets(oneline,LINELEN,inf)) {
  602.         fprintf(stderr,"fromtype1: no currentfile eexec found\n");
  603.         exit(1);
  604.     }
  605.     oneline[16] = 0;
  606.     if(strcmp(oneline,"currentfile eexe") == 0) 
  607.         break;
  608.     }
  609.  
  610. /* read all the hex bytes into the hex buffer */
  611.     hexbytes = 0;
  612.     while(fgets(oneline,LINELEN,inf)) {
  613.     hptr = (unsigned char *)oneline;
  614.     while(*hptr) {
  615.         if(hextab[*hptr] != NOTHEX)
  616.         hexdat[hexbytes++] = *hptr;
  617.         hptr++;
  618.     }
  619.     }
  620.     fclose(inf);
  621.  
  622. /* check number of hex bytes */
  623.     if(hexbytes & 1) 
  624.     hexbytes--;
  625.     datbytes = hexbytes/2;
  626.  
  627. /* translate hex data to binary */
  628.     hptr = hexdat;
  629.     bptr = decdat;
  630.     c = datbytes;
  631.     while(c--) {
  632.     *bptr++  = (hextab[hptr[0]]<<4)+hextab[hptr[1]];
  633.     hptr += 2;
  634.     }
  635.  
  636. /* decrypt the data */
  637.     resetdecrypt(55665);
  638.     decryptdata(decdat,decdat,datbytes);
  639.  
  640.     if(debugtype1) {
  641.     outf = fopen("debug.bin","w");
  642.     fwrite(decdat+4,datbytes-4,1,outf);
  643.     fclose(outf);
  644.  
  645.     }
  646.     free(hexdat);
  647.     return decdat;
  648. }
  649.  
  650. /* 
  651.  *    fake file reading funcs
  652.  *
  653.  *
  654.  */
  655. static void fakefopen()
  656. {
  657.     fakepos = 0;
  658.     fakemax = datbytes;
  659. }
  660.  
  661. #define NL    (0x0a)
  662. #define CR    (0x0d)
  663.  
  664. static void fakegettoken(char *str)
  665. {
  666.     int c;
  667.     unsigned char *cptr;
  668.  
  669.     cptr = bindat+fakepos;
  670.     c = *cptr++;
  671.     fakepos++;
  672.     if(c != NL && c != CR) {
  673.     while(isspace(c)) {
  674.         c = *cptr++;
  675.         fakepos++;
  676.     }
  677.     while (fakepos<fakemax && !isspace(c)) {
  678.         *str++ = c;
  679.         c = *cptr++;
  680.         fakepos++;
  681.     }
  682.     if(c == NL || c == CR)
  683.         fakepos--;
  684.     }
  685.     *str = 0;
  686.     if(fakepos>fakemax) {
  687.     fprintf(stderr,"fromtype1: unexpected eof\n");
  688.     exit(1);
  689.     }
  690. }
  691.  
  692. static int fakefgets(char *buf,int max)
  693. {
  694.     unsigned char *cptr;
  695.  
  696.     cptr = (unsigned char *)(bindat+fakepos);
  697.     while(max--) {
  698.     *buf++ = *cptr;
  699.     fakepos++;
  700.     if(*cptr == NL || *cptr == CR)
  701.         return 1;
  702.     cptr++;
  703.     if(fakepos>fakemax)
  704.         return 0;
  705.     }
  706.     return 0;
  707. }
  708.  
  709. static unsigned char *fakefread(int n)
  710. {
  711.     fakepos += n;
  712.     return bindat+fakepos-n;
  713. }
  714.  
  715. static void setcharlist()
  716. {
  717.     char *name;
  718.     int i, j;
  719.  
  720.     if(strncmp(fname,"Symbol",6) == 0) {
  721.         for(i=0; i<NSYMBL; i++) 
  722.         scharlist[i].prog = -1;
  723.         for(i=0; i<NSYMBL-1; i++) {
  724.             name = scharlist[i].name;
  725.             if(name) {
  726.                 for(j=0; j<nchars; j++) {
  727.                 if(charname[j]&&(strcmp(name,charname[j]) == 0))
  728.                     scharlist[i].prog = j;
  729.                 }
  730.             }
  731.         }
  732.     } else {
  733.         if(strncmp(fname,"ZapfDingbats",12) == 0) {
  734.             for(i=0; i<NZAPFD; i++) 
  735.             zcharlist[i].prog = -1;
  736.             for(i=0; i<NZAPFD-1; i++) {
  737.                 name = zcharlist[i].name;
  738.                 if(name) {
  739.                     for(j=0; j<nchars; j++) {
  740.                         if(charname[j]&&(strcmp(name,charname[j]) == 0))
  741.                             zcharlist[i].prog = j;
  742.                     }
  743.                 }
  744.             }
  745.         } else {
  746.             for(i=0; i < ACCENTBASE + NACCENT; i++) 
  747.             charlist[i].prog = -1;
  748.             for(i=0; i < NASCII; i++) {
  749.                 name = charlist[i].name;
  750.                 if(name) {
  751.                     for(j=0; j<nchars; j++) {
  752.                         if(charname[j]&&(strcmp(name,charname[j]) == 0))
  753.                 charlist[i].prog = j;
  754.                     }
  755.                 }
  756.             }
  757.             for(i=0; i < NACCENT; i++) {
  758.                 name = accentlist[i].name;
  759.                 if(name) {
  760.                     for(j=0; j<nchars; j++) {
  761.                         if(charname[j]&&(strcmp(name,charname[j]) == 0)) {
  762. #ifdef DEBUGGING
  763.                 fprintf(stderr, "Found accent %s, assiging id %d\n",
  764.                 name, i + ACCENTBASE);
  765. #endif
  766.                 charlist[i + ACCENTBASE].prog = j;
  767.             }
  768.                     }
  769.                 }
  770.             }
  771.         }
  772.     }
  773. }
  774.  
  775. /*
  776.  *    pc stack support
  777.  *
  778.  */
  779. static void initpcstack()
  780. {
  781.    pcsp = 0;
  782. }
  783.  
  784. static void pushpc(unsigned char *pc)
  785. {
  786.    pcstack[pcsp] = pc;
  787.    pcsp++;
  788. }
  789.  
  790. static unsigned char *poppc()
  791. {
  792.    pcsp--;
  793.    if(pcsp<0) {
  794.          fprintf(stderr,"\nYUCK: pc stack under flow\n"); 
  795.     pcsp = 0;
  796.     return 0;
  797.    }
  798.    return pcstack[pcsp];
  799. }
  800.  
  801. /*
  802.  *    Data stack support
  803.  *
  804.  */
  805. static void initstack()
  806. {
  807.    sp = 0;
  808. }
  809.  
  810. static void push(int val)
  811. {
  812.    stack[sp] = val;
  813.    sp++;
  814. }
  815.  
  816. static int pop()
  817. {
  818.    sp--;
  819.    if(sp<0) {
  820.          fprintf(stderr,"\nYUCK: stack under flow\n"); 
  821.     sp = 0;
  822.     return 0;
  823.    }
  824.    return stack[sp];
  825. }
  826.  
  827. /*
  828.  *    call/return data stack
  829.  *
  830.  */
  831. static void initretstack()
  832. {
  833.    retsp = 0;
  834. }
  835.  
  836. static void retpush(int val)
  837. {
  838.    retstack[retsp] = val;
  839.    retsp++;
  840. }
  841.  
  842. static int retpop()
  843. {
  844.    retsp--;
  845.    if(retsp<0) {
  846.          fprintf(stderr,"\nYUCK: ret stack under flow\n"); 
  847.     retsp = 0;
  848.     return 0;
  849.    }
  850.    return retstack[retsp];
  851. }
  852.  
  853. /*
  854.  * the three subrs
  855.  *
  856.  */
  857. static void subr0()
  858. {
  859.     int x0, y0;
  860.     int x1, y1;
  861.     int x2, y2;
  862.     int x3, y3;
  863.     int xpos, ypos, noise;
  864.  
  865.     ypos = pop();
  866.     xpos = pop();
  867.     noise = pop();
  868.     if(coordpos!=7) {
  869.     fprintf(stderr,"subr0: bad poop\n");
  870.     exit(1);
  871.     }
  872.     x0 =  coordsave[0][0];
  873.     y0 =  coordsave[0][1];
  874.  
  875.     x1 =  coordsave[1][0]+x0;
  876.     y1 =  coordsave[1][1]+y0;
  877.     x2 =  coordsave[2][0];
  878.     y2 =  coordsave[2][1];
  879.     x3 =  coordsave[3][0];
  880.     y3 =  coordsave[3][1];
  881.     rcurveto(x1,y1,x1+x2,y1+y2,x1+x2+x3,y1+y2+y3);
  882.     x1 =  coordsave[4][0];
  883.     y1 =  coordsave[4][1];
  884.     x2 =  coordsave[5][0];
  885.     y2 =  coordsave[5][1];
  886.     x3 =  coordsave[6][0];
  887.     y3 =  coordsave[6][1];
  888.     rcurveto(x1,y1,x1+x2,y1+y2,x1+x2+x3,y1+y2+y3);
  889.     getpos(&x0,&y0);
  890.     retpush(y0);
  891.     retpush(x0);
  892.     incusp = 0;
  893. }
  894.  
  895. static void subr1()
  896. {
  897.     coordpos = 0;
  898.     incusp = 1;
  899. }
  900.  
  901. static void subr2()
  902. {
  903.     int x, y;
  904.  
  905.     getmove(&x,&y);
  906.     if(coordpos>=7) {
  907.     fprintf(stderr,"subr2: bad poop\n");
  908.     exit(1);
  909.     }
  910.     coordsave[coordpos][0] = x;
  911.     coordsave[coordpos][1] = y;
  912.     coordpos++;
  913. }
  914.  
  915. puthexdata(outf,buf,n)
  916. FILE *outf;
  917. unsigned char *buf;
  918. int n;
  919. {
  920.     while(n--) 
  921.      fprintf(outf,"%02x",*buf++);
  922.      fprintf(outf,"\n");
  923. }
  924.  
  925. /*
  926.  * run the character program    
  927.  *
  928.  *
  929.  */
  930. static void drawchar(int c)
  931. {
  932. #ifdef DEBUGGING
  933. fprintf(stderr,"\n\nDrawing char %d: name: [%s]\n",c,charname[c]);
  934. fprintf(stderr,"N bytes %d\n",charlen[c]);
  935. puthexdata(stderr,chars[c],charlen[c]);
  936. fprintf(stderr,"\n\n");
  937.  
  938. #endif
  939.     x_offset = y_offset = 0;
  940.     poly_beginchar();
  941.     spline_beginchar();
  942.     initstack();
  943.     initpcstack();
  944.     initretstack();
  945.     pc = chars[c];
  946.     runprog();
  947.     poly_endchar();
  948.     spline_endchar();
  949. }
  950.  
  951. static void drawchar_seac(int c, int accentflag)
  952. {
  953.     if(!accentflag) {
  954.     poly_beginchar();
  955.     spline_beginchar();
  956.     }
  957.     initstack();
  958.     initpcstack();
  959.     initretstack();
  960.     pc = chars[c];
  961.     runprog();
  962.     if(accentflag) {
  963.     poly_endchar();
  964.     spline_endchar();
  965.     }
  966. }
  967.  
  968. static void seac(int asb, int adx, int ady, int bchar, int achar)
  969. {
  970.     int    i, j;
  971.  
  972.     for(i = 0; i < NACCENT; i++) {
  973.     if(achar == accentlist[i].code) {
  974. #ifdef DEBUGGING
  975.         fprintf(stderr, "\nin seac, drawing char %03o and %03o\n",
  976.         bchar, achar);
  977. #endif
  978.         x_offset = adx;
  979.         y_offset = ady;
  980.         drawchar_seac(charlist[ACCENTBASE + i].prog, 0);
  981.  
  982.         x_offset = 0;
  983.         y_offset = 0;
  984.         for(j = 0; j < NACCENT; j++) {    /* look through accents first */
  985.         if(bchar == accentlist[j].code) {
  986.             drawchar_seac(charlist[ACCENTBASE + j].prog, 1);
  987.             break;
  988.         }
  989.         }
  990.  
  991.         if(j == NACCENT) {
  992.         for(j = 0; j < NASCII; j++) {
  993.             if(bchar == charlist[j].code) {
  994.             drawchar_seac(charlist[j].prog, 1);
  995.             break;
  996.             }
  997.         }
  998.         }
  999.         break;
  1000.     }
  1001.     }
  1002.     if(i == NACCENT) {
  1003. #ifdef DEBUGGING
  1004.     fprintf(stderr, "\nin seac, drawing char %03o\n", bchar);
  1005. #endif
  1006.     drawchar(achar);
  1007.     }
  1008. }
  1009.  
  1010. /*
  1011.  *    execute the program:
  1012.  *
  1013.  *
  1014.  */
  1015. #define HSTEM        (1)
  1016. #define VSTEM        (3)
  1017. #define VMOVETO        (4)
  1018. #define RLINETO        (5)
  1019. #define HLINETO        (6)
  1020. #define VLINETO        (7)
  1021. #define RRCURVETO    (8)
  1022. #define CLOSEPATH    (9)
  1023. #define CALLSUBR    (10)
  1024. #define RETURN        (11)
  1025. #define HSBW        (13)
  1026. #define ENDCHAR        (14)
  1027. #define RMOVETO        (21)
  1028. #define HMOVETO        (22)
  1029. #define VHCURVETO    (30)
  1030. #define HVCURVETO    (31)
  1031. #define DOTSECTION    (256+0)
  1032. #define VSTEM3        (256+1)
  1033. #define HSTEM3        (256+2)
  1034. #define SEAC        (256+6)
  1035. #define SBW        (256+7)
  1036. #define DIV        (256+12)
  1037. #define CALLOTHERSUBR    (256+16)
  1038. #define POP        (256+17)
  1039. #define SETCURRENTPOINT    (256+33)
  1040. #define WHAT0        (0)
  1041.  
  1042. static int docommand(int cmd)
  1043. {
  1044.     int x, y, w;
  1045.     int dx1, dy1;
  1046.     int dx2, dy2;
  1047.     int dx3, dy3;
  1048.     int i, sub, n, p;
  1049.     int    achar, bchar, adx, ady, asb;
  1050.     unsigned char *subpc;
  1051.  
  1052.     switch(cmd) {
  1053.     case WHAT0:
  1054.         fprintf(stderr,"\nYUCK: WHAT0\n"); 
  1055.         break;
  1056.     case HSTEM:
  1057.         pop();
  1058.         pop();
  1059.         break;
  1060.     case VSTEM:        
  1061.         pop();
  1062.         pop();
  1063.         break;
  1064.     case VMOVETO:
  1065.         y = pop();
  1066.         rmoveto(0,y);
  1067.         break;
  1068.     case RLINETO:
  1069.         y = pop();
  1070.         x = pop();
  1071.         rlineto(x,y);
  1072.         break;
  1073.     case HLINETO:
  1074.         x = pop();
  1075.         rlineto(x,0);
  1076.         break;
  1077.     case VLINETO:
  1078.         y = pop();
  1079.         rlineto(0,y);
  1080.         break;
  1081.     case RRCURVETO:
  1082.         dy3 = pop();
  1083.         dx3 = pop();
  1084.         dy2 = pop();
  1085.         dx2 = pop();
  1086.         dy1 = pop();
  1087.         dx1 = pop();
  1088.         rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3);
  1089.         break;
  1090.     case CLOSEPATH:
  1091.         closepath();
  1092.         break;
  1093.     case CALLSUBR:
  1094.         sub = pop();
  1095.         subpc = subrs[sub];
  1096.         if(!subpc) {
  1097.         fprintf(stderr,"\nYUCK no sub addr\n");
  1098.         }
  1099.         pushpc(pc);
  1100.         pc = subpc;
  1101.         break;
  1102.     case RETURN:
  1103.         pc = poppc();
  1104.         break;
  1105.     case HSBW:
  1106.         w = pop();
  1107.         x = pop();
  1108.         poly_width(w);
  1109.         spline_width(w);
  1110.         sbpoint(x,0);
  1111.         break;
  1112.     case ENDCHAR:
  1113.         closepath();
  1114.         break;
  1115.     case RMOVETO:
  1116.         y = pop();
  1117.         x = pop();
  1118.         rmoveto(x,y);
  1119.         break;
  1120.     case HMOVETO:
  1121.         x = pop();
  1122.         rmoveto(x,0);
  1123.         break;
  1124.     case VHCURVETO:
  1125.         dy3 = 0;
  1126.         dx3 = pop();
  1127.         dy2 = pop();
  1128.         dx2 = pop();
  1129.         dy1 = pop();
  1130.         dx1 = 0;
  1131.         rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3);
  1132.         break;
  1133.     case HVCURVETO:
  1134.         dy3 = pop();
  1135.         dx3 = 0;
  1136.         dy2 = pop();
  1137.         dx2 = pop();
  1138.         dy1 = 0;
  1139.         dx1 = pop();
  1140.         rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3);
  1141.         break;
  1142.     case DOTSECTION:
  1143.         break;
  1144.     case VSTEM3:
  1145.         pop();
  1146.         pop();
  1147.         pop();
  1148.         pop();
  1149.         pop();
  1150.         pop();
  1151.         break;
  1152.     case HSTEM3:
  1153.         pop();
  1154.         pop();
  1155.         pop();
  1156.         pop();
  1157.         pop();
  1158.         pop();
  1159.         break;
  1160.     case SEAC:
  1161.         achar = pop();
  1162.         bchar = pop();
  1163.         ady   = pop();
  1164.         adx   = pop();
  1165.         asb   = pop();
  1166.         seac(asb, adx, ady, bchar, achar);
  1167.         return 0;
  1168.         break;
  1169.     case SBW:
  1170.         x = pop();
  1171.         y = pop();
  1172.         fprintf(stderr,"sbw: width: %d %d\n",x,y);
  1173.         poly_width(x);
  1174.         spline_width(x);
  1175.         y = pop();
  1176.         x = pop();
  1177.         fprintf(stderr,"sbw: side: %d %d\n",x,y);
  1178.         sbpoint(x,y);
  1179.         break;
  1180.     case DIV:
  1181.         x = pop();
  1182.         y = pop();
  1183.         push(x/y);
  1184.         break;
  1185.     case CALLOTHERSUBR:
  1186.         sub = pop();
  1187.         n = pop();
  1188.         if(sub == 0)
  1189.         subr0();
  1190.         else if(sub == 1)
  1191.         subr1();
  1192.         else if(sub == 2)
  1193.         subr2();
  1194.         else {
  1195.         dfprintf(stderr,"\nYUCK nargs %d\n",n);
  1196.         for(i=0; i<n; i++) {
  1197.             dfprintf(stderr,"\nYUCK pretpush %d\n",i);
  1198.             retpush(pop());
  1199.         }
  1200.         }
  1201.         break;
  1202.     case POP:
  1203.         push(retpop());
  1204.         break;
  1205.     case SETCURRENTPOINT:
  1206.         y = pop();
  1207.         x = pop();
  1208.         sbpoint(x,y);
  1209.         break;
  1210.     default:
  1211.         fprintf(stderr,"\nYUCK bad instruction %d\n",cmd);
  1212.         break;
  1213.     }
  1214.     if(pc == 0 || cmd == ENDCHAR || cmd == WHAT0 || cmd == SEAC)
  1215.     return 0;
  1216.     else
  1217.     return 1;
  1218. }
  1219.  
  1220. /*
  1221.  *    Character interpreter
  1222.  *
  1223.  */
  1224. static void runprog()
  1225. {
  1226.     long v, w, num, cmd;
  1227.  
  1228. #ifdef PRINTDEBUG
  1229.     unsigned char    *printpc;
  1230.     long        printed;
  1231.  
  1232.     /* print program */
  1233.     printpc = pc;
  1234.     printed = 0;
  1235.     while(printpc && *printpc != WHAT0 && *printpc != ENDCHAR) {
  1236.     v  = *printpc++;
  1237.     if(v>=0 && v<=31) {
  1238.         if(v == 12) {
  1239.         w  = *printpc++;
  1240.         cmd = 256+w;
  1241.         } else 
  1242.         cmd = v;
  1243.         switch(cmd) {
  1244.         case HSTEM:        fprintf(stderr, "HSTEM"); break;
  1245.         case VSTEM:       fprintf(stderr, "VSTEM"); break;
  1246.         case VMOVETO:     fprintf(stderr, "VMOVE"); break;
  1247.         case RLINETO:     fprintf(stderr, "RLINE"); break;
  1248.         case HLINETO:     fprintf(stderr, "HLINE"); break;
  1249.         case VLINETO:     fprintf(stderr, "VLINE"); break;
  1250.         case RRCURVETO:     fprintf(stderr, "RRCRV"); break;
  1251.         case CLOSEPATH:     fprintf(stderr, "CLSEP"); break;
  1252.         case CALLSUBR:     fprintf(stderr, "CLLSB"); break;
  1253.         case RETURN:     fprintf(stderr, "RETRN"); break;
  1254.         case HSBW:         fprintf(stderr, "HSBW "); break;
  1255.         case ENDCHAR:     fprintf(stderr, "ENDCH"); break;
  1256.         case RMOVETO:     fprintf(stderr, "RMOVE"); break;
  1257.         case HMOVETO:     fprintf(stderr, "HMOVE"); break;
  1258.         case VHCURVETO:     fprintf(stderr, "VHCRV"); break;
  1259.         case HVCURVETO:     fprintf(stderr, "HVCRV"); break;
  1260.         case DOTSECTION:     fprintf(stderr, "DTSCT"); break;
  1261.         case VSTEM3:     fprintf(stderr, "VSTM3"); break;
  1262.         case HSTEM3:     fprintf(stderr, "HSTM3"); break;
  1263.         case SEAC:         fprintf(stderr, "SEAC "); printpc = 0; break;
  1264.         case SBW:         fprintf(stderr, "SBW  "); break;
  1265.         case DIV:         fprintf(stderr, "DIV  "); break;
  1266.         case CALLOTHERSUBR: fprintf(stderr, "COSBR"); break;
  1267.         case POP:         fprintf(stderr, "POP  "); break;
  1268.         case SETCURRENTPOINT:fprintf(stderr,"SETPT"); break;
  1269.         case WHAT0:     fprintf(stderr, "WHAT0"); break;
  1270.         default:        fprintf(stderr, "ERROR"); break;
  1271.         }
  1272.     } else if(v>=32 && v<=246) {
  1273.         num = v-139;
  1274.         fprintf(stderr, "%5d", num);
  1275.     } else if(v>=247 && v<=250) {
  1276.         w  = *printpc++;
  1277.         num = (v-247)*256+w+108;
  1278.         fprintf(stderr, "%5d", num);
  1279.     } else if(v>=251 && v<=254) {
  1280.         w  = *printpc++;
  1281.         num = -(v-251)*256-w-108;
  1282.         fprintf(stderr, "%5d", num);
  1283.     } else if(v == 255) {
  1284.         num  = *printpc++;
  1285.         num <<= 8;
  1286.         num |= *printpc++;
  1287.         num <<= 8;
  1288.         num |= *printpc++;
  1289.         num <<= 8;
  1290.         num |= *printpc++;
  1291.         fprintf(stderr, "%5d", num);
  1292.     }
  1293.     if(printed++ % 12 == 11)
  1294.         fprintf(stderr, "\n");
  1295.     else
  1296.         fprintf(stderr, " ");
  1297.     }
  1298.     if(printpc == 0) {
  1299.     fprintf(stderr,"OK  pc is 0\n");
  1300.     exit(0);
  1301.     } else {
  1302.     if(*printpc == ENDCHAR) 
  1303.         fprintf(stderr, "ENDCH");
  1304.      }
  1305. #endif
  1306.  
  1307.     while(1) {
  1308.     v  = *pc++;
  1309.     if(v>=0 && v<=31) {
  1310.         if(v == 12) {
  1311.         w  = *pc++;
  1312.         cmd = 256+w;
  1313.         } else 
  1314.         cmd = v;
  1315.         if(!docommand(cmd)) {
  1316.         return;
  1317.         }
  1318.     } else if(v>=32 && v<=246) {
  1319.         num = v-139;
  1320.         push(num);
  1321.     } else if(v>=247 && v<=250) {
  1322.         w  = *pc++;
  1323.         num = (v-247)*256+w+108;
  1324.         push(num);
  1325.     } else if(v>=251 && v<=254) {
  1326.         w  = *pc++;
  1327.         num = -(v-251)*256-w-108;
  1328.         push(num);
  1329.     } else if(v == 255) {
  1330.         num  = *pc++;
  1331.         num <<= 8;
  1332.         num |= *pc++;
  1333.         num <<= 8;
  1334.         num |= *pc++;
  1335.         num <<= 8;
  1336.         num |= *pc++;
  1337.         push(num);
  1338.     }
  1339.     }
  1340. }
  1341.  
  1342. /*
  1343.  *    genobjfont -
  1344.  *        generate an object font.
  1345.  *
  1346.  */
  1347. static objfnt *genobjfont(int savesplines,int fullset)
  1348. {
  1349.     int i, j, c, d;
  1350.     objfnt *fnt;
  1351.     int maxchars;
  1352.  
  1353.     if (strncmp(fname,"Symbol",6) == 0) {
  1354.         if(savesplines)
  1355.         fnt = newobjfnt(SP_TYPE,32,32+NSYMBL-1,1000);
  1356.         else
  1357.             fnt = newobjfnt(PO_TYPE,32,32+NSYMBL-1,1000);
  1358.         for(i=0; i<NSYMBL; i++) {
  1359.             c = i+32;
  1360.             if(scharlist[i].prog>=0) {
  1361.                 nshorts = 0;
  1362.                 sp_nshorts = 0;
  1363.                 drawchar(scharlist[i].prog);
  1364.                 if(savesplines)
  1365.                     addchardata(fnt,c,sp_chardata,sp_nshorts);
  1366.                 else
  1367.                     addchardata(fnt,c,chardata,nshorts);
  1368.                 addcharmetrics(fnt,c,thecharwidth,0);
  1369.             } else 
  1370.                 if(c == ' ') {
  1371.                     printf("faking space %d\n",i);
  1372.                     fakechar(fnt,' ',400);
  1373.                 }
  1374.         }
  1375.     } else {
  1376.         if(strncmp(fname,"ZapfDingbats",12) == 0) {
  1377.             if(savesplines)
  1378.                 fnt = newobjfnt(SP_TYPE,32,32+NZAPFD-1,1000);
  1379.             else
  1380.                 fnt = newobjfnt(PO_TYPE,32,32+NZAPFD-1,1000);
  1381.             for(i=0; i<NZAPFD; i++) {
  1382.                 c = i+32;
  1383.                 if(zcharlist[i].prog>=0) {
  1384.                     nshorts = 0;
  1385.                     sp_nshorts = 0;
  1386.                     drawchar(zcharlist[i].prog);
  1387.                     if(savesplines)
  1388.                         addchardata(fnt,c,sp_chardata,sp_nshorts);
  1389.                     else
  1390.                         addchardata(fnt,c,chardata,nshorts);
  1391.                     addcharmetrics(fnt,c,thecharwidth,0);
  1392.                 } else 
  1393.                     if(c == ' ') {
  1394.                         printf("faking space %d\n",i);
  1395.                         fakechar(fnt,' ',400);
  1396.                     }
  1397.             }
  1398.         } else {
  1399.  
  1400.         maxchars = 0;
  1401.             for(i=0; i<NASCII; i++) {
  1402.                 if(charlist[i].prog>=0)
  1403.              maxchars = i;
  1404.         }
  1405.         maxchars++;
  1406.  
  1407.         if(maxchars>NASCII)
  1408.          maxchars = NASCII;
  1409.         if(!fullset) {
  1410.         if(maxchars>95)
  1411.              maxchars = 95;
  1412.         }
  1413.  
  1414.             if(savesplines)
  1415.                 fnt = newobjfnt(SP_TYPE,32,32+maxchars-1,1000);
  1416.             else
  1417.                 fnt = newobjfnt(PO_TYPE,32,32+maxchars-1,1000);
  1418.             for(i=0; i<maxchars; i++) {
  1419.                 c = i+32;
  1420.                 if(charlist[i].prog>=0) {
  1421.                     nshorts = 0;
  1422.                     sp_nshorts = 0;
  1423. #ifdef DEBUGGGING
  1424.             fprintf(stderr, "\n\ndrawing character '%c' (%03o %d)\n",
  1425.             c, c, c);
  1426. #endif
  1427.                     drawchar(charlist[i].prog);
  1428.                     if(savesplines)
  1429.                         addchardata(fnt,c,sp_chardata,sp_nshorts);
  1430.                     else
  1431.                         addchardata(fnt,c,chardata,nshorts);
  1432.                     addcharmetrics(fnt,c,thecharwidth,0);
  1433.                 } else 
  1434.                     if(c == ' ') {
  1435.                         printf("faking space %d\n",i);
  1436.                         fakechar(fnt,' ',400);
  1437.                     }
  1438.             }
  1439.         } 
  1440.     }
  1441.     return fnt;
  1442. }
  1443.  
  1444. objfnt *readtype1(char *infont,float beztolerance,int fullset)
  1445. {
  1446.     int i, j, k, d, index, len;
  1447.     int nread, namelen, savesplines;
  1448.     char *cptr;
  1449.     objfnt *fnt;
  1450.  
  1451.     if(beztolerance<0.0001) {
  1452.     savesplines = 1;
  1453.     beztol = 100.0;
  1454.     } else  {
  1455.     savesplines = 0;
  1456.     beztol = beztolerance;
  1457.     }
  1458.  
  1459. /* read the font matrix from the font */
  1460.     *fname = NULL;
  1461.     readfontmatrix(infont,mat);
  1462.  
  1463. /* decode the font data */
  1464.     bindat = decodetype1(infont);
  1465.  
  1466. /* open the input file */
  1467.     fakefopen();
  1468.  
  1469. /* init the charname, charlen and sublen arrays */
  1470.     nchars = 0;
  1471.     for(i=0; i<MAXCHARS; i++) {
  1472.     charname[i] = 0;
  1473.     charlen[i] = 0;
  1474.     }
  1475.     for(i=0; i<MAXSUBRS; i++) 
  1476.     sublen[i] = 0;
  1477.  
  1478. /* look for the /Subrs def and get nsubrs */
  1479.     while(1) {
  1480.     if(!fakefgets(oneline,LINELEN)) {
  1481.         fprintf(stderr,"fromtype1: no /Subrs found\n");
  1482.         exit(1);
  1483.     }
  1484.     cptr = strchr(oneline,'/');
  1485.     if(cptr) {
  1486.         if(strncmp(cptr,"/Subrs",6) == 0) {
  1487.         nsubrs = atoi(cptr+6);
  1488.         break;
  1489.         }
  1490.     }
  1491.     }
  1492.  
  1493. /* read the Subrs in one by one */
  1494.     for(i=0; i<nsubrs; i++) 
  1495.     sublen[i] = 0;
  1496.     for(i=0; i<nsubrs; i++) {
  1497.     for(k=0; k<MAXTRIES; k++) {
  1498.         fakegettoken(tok);
  1499.         if(strcmp(tok,"dup") == 0)
  1500.         break;
  1501.     }
  1502.     if(k == MAXTRIES) {
  1503.         fprintf(stderr,"dup for subr %d not found in range\n");
  1504.         exit(1);
  1505.     }
  1506.  
  1507. /* get the Subr index here */
  1508.     fakegettoken(tok);
  1509.     index = atoi(tok);
  1510.  
  1511. /* check to make sure it is in range */
  1512.     if(index<0 || index>nsubrs) {
  1513.         fprintf(stderr,"bad Subr index %d\n",index);
  1514.         exit(1);
  1515.     }
  1516.  
  1517. /* get the number of bytes to read */
  1518.     fakegettoken(tok);
  1519.     nread = atoi(tok);
  1520.     fakegettoken(tok);
  1521.  
  1522. /* read in the subroutine */
  1523.     sublen[index] = nread;
  1524.     subrs[index] = fakefread(nread);
  1525.     fakegettoken(tok);
  1526.     }
  1527.  
  1528. /* look for the CharStrings */
  1529.     while(1) {
  1530.     fakegettoken(tok);
  1531.     cptr = strchr(tok,'/');
  1532.     if(cptr && strcmp(cptr,"/CharStrings") == 0)
  1533.         break;
  1534.     }
  1535.  
  1536.     fakegettoken(tok);    /* skip ncharscrings */
  1537.     fakegettoken(tok);    /* skip dict */
  1538.     fakegettoken(tok);    /* skip dup */
  1539.     fakegettoken(tok);    /* skip begin */
  1540.     fakegettoken(tok);    /* skip newline */
  1541.  
  1542. /* read the CharStrings one by one */
  1543.     for(i=0; i<MAXCHARS; i++) { 
  1544.  
  1545. /* check for end */
  1546.     fakegettoken(tok);
  1547.     if(strcmp(tok,"end") == 0) 
  1548.         break;
  1549.  
  1550. /* get the char name and allocate space for it */
  1551.     namelen = strlen(tok);
  1552.     charname[i] = (char *)mymalloc(namelen+1);
  1553.     strcpy(charname[i],tok);
  1554.  
  1555. /* get the number of bytes to read */
  1556.     fakegettoken(tok);
  1557.     nread = atoi(tok);
  1558.     fakegettoken(tok);
  1559.  
  1560. /* read in the char description */
  1561.     charlen[i] = nread;
  1562.     chars[i] = fakefread(nread);
  1563.  
  1564. /* skip the end of line */
  1565.     fakegettoken(tok);
  1566.     fakegettoken(tok);
  1567.     nchars++;
  1568.     }
  1569.  
  1570. /* decrypt the character descriptions */
  1571.     decryptall();
  1572.     setcharlist();
  1573.  
  1574. /* make the obj font */
  1575.     fnt = genobjfont(savesplines,fullset);
  1576.  
  1577. /* calculate the bboxes */
  1578.     calccharbboxes(fnt);
  1579.  
  1580. /* free malloced stuff */
  1581.     free(bindat);
  1582.     for(i=0; i<MAXCHARS; i++) { 
  1583.     if(charname[i])
  1584.         free(charname[i]);
  1585.     }
  1586.     return fnt;
  1587. }
  1588.  
  1589. #ifdef FINDIT
  1590. printchardata(i)
  1591. int i;
  1592. {
  1593.     int n;
  1594.     unsigned char *cptr;
  1595.  
  1596.     printf("name: [%s] proglen %d\n",charname[i],charlen[i]);
  1597.     n = charlen[i];
  1598.     cptr = chars[i];
  1599.     while(n--) {
  1600.     printf("%02x ",*cptr++);
  1601.     
  1602.     }
  1603.     printf("\n");
  1604. }
  1605. #endif
  1606.